static void maybe_connect(struct backend_info *be)
{
- if (be->netif != NULL && be->frontend_state == XenbusStateConnected) {
+ if (be->netif && (be->frontend_state == XenbusStateConnected))
connect(be);
- }
+}
+
+static void xen_net_read_rate(struct xenbus_device *dev,
+ unsigned long *bytes, unsigned long *usec)
+{
+ char *s, *e;
+ unsigned long b, u;
+ char *ratestr;
+
+ /* Default to unlimited bandwidth. */
+ *bytes = ~0UL;
+ *usec = 0;
+
+ ratestr = xenbus_read(XBT_NULL, dev->nodename, "rate", NULL);
+ if (IS_ERR(ratestr))
+ return;
+
+ s = ratestr;
+ b = simple_strtoul(s, &e, 10);
+ if ((s == e) || (*e != ','))
+ goto fail;
+
+ s = e + 1;
+ u = simple_strtoul(s, &e, 10);
+ if ((s == e) || (*e != '\0'))
+ goto fail;
+
+ *bytes = b;
+ *usec = u;
+
+ kfree(ratestr);
+ return;
+
+ fail:
+ WPRINTK("Failed to parse network rate limit. Traffic unlimited.\n");
+ kfree(ratestr);
}
return;
}
+ xen_net_read_rate(dev, &be->netif->credit_bytes,
+ &be->netif->credit_usec);
+ be->netif->remaining_credit = be->netif->credit_bytes;
+
xenbus_switch_state(dev, XenbusStateConnected);
}
import os
import random
+import re
from xen.xend import sxp
from xen.xend import XendRoot
random.randint(0x00, 0xff) ]
return ':'.join(map(lambda x: "%02x" % x, mac))
+rate_re = re.compile("^([0-9]+)([GMK]?)([Bb])/s(@([0-9]+)([mu]?)s)?$")
+
+def parseRate(ratestr):
+ """if parsing fails this will return default of unlimited rate"""
+ bytes_per_interval = 0xffffffffL # 0xffffffff # big default
+ interval_usecs = 0L # disabled
+
+ m = rate_re.match(ratestr)
+ if m:
+ bytes_per_sec = long(m.group(1))
+
+ if m.group(2) == 'G':
+ bytes_per_sec *= 1000 * 1000 * 1000
+ elif m.group(2) == 'M':
+ bytes_per_sec *= 1000 * 1000
+ elif m.group(2) == 'K':
+ bytes_per_sec *= 1000
+
+ if m.group(3) == 'b':
+ bytes_per_sec /= 8
+
+ if m.group(5) is None:
+ interval_usecs = 50000L # 50ms default
+ else:
+ interval_usecs = long(m.group(5))
+ if m.group(6) == '':
+ interval_usecs *= 1000 * 1000
+ elif m.group(6) == 'm':
+ interval_usecs *= 1000
+
+ bytes_per_interval = (bytes_per_sec * interval_usecs) / 1000000L
+
+ # overflow / underflow checking: default to unlimited rate
+ if bytes_per_interval == 0 or bytes_per_interval > 0xffffffffL or \
+ interval_usecs == 0 or interval_usecs > 0xffffffffL:
+ bytes_per_interval = 0xffffffffL
+ interval_usecs = 0L
+
+ return "%lu,%lu" % (bytes_per_interval, interval_usecs)
+
+
+write_rate_G_re = re.compile('^([0-9]+)000000000(B/s@[0-9]+us)$')
+write_rate_M_re = re.compile('^([0-9]+)000000(B/s@[0-9]+us)$')
+write_rate_K_re = re.compile('^([0-9]+)000(B/s@[0-9]+us)$')
+write_rate_s_re = re.compile('^([0-9]+[GMK]?B/s@[0-9]+)000000us$')
+write_rate_m_re = re.compile('^([0-9]+[GMK]?B/s@[0-9]+)000us$')
+
+def formatRate(rate):
+ (bytes_per_interval, interval_usecs) = map(long, rate.split(','))
+
+ if interval_usecs != 0:
+ bytes_per_second = (bytes_per_interval * 1000 * 1000) / interval_usecs
+ else:
+ bytes_per_second = 0xffffffffL
+
+ ratestr = "%uB/s@%uus" % (bytes_per_second, interval_usecs)
+
+ # look for '000's
+ m = write_rate_G_re.match(ratestr)
+ if m:
+ ratestr = m.group(1) + "G" + m.group(2)
+ else:
+ m = write_rate_M_re.match(ratestr)
+ if m:
+ ratestr = m.group(1) + "M" + m.group(2)
+ else:
+ m = write_rate_K_re.match(ratestr)
+ if m:
+ ratestr = m.group(1) + "K" + m.group(2)
+
+ m = write_rate_s_re.match(ratestr)
+ if m:
+ ratestr = m.group(1) + "s"
+ else:
+ m = write_rate_m_re.match(ratestr)
+ if m:
+ ratestr = m.group(1) + "ms"
+
+ return ratestr
+
class NetifController(DevController):
"""Network interface controller. Handles all network devices for a domain.
bridge = sxp.child_value(config, 'bridge')
mac = sxp.child_value(config, 'mac')
vifname = sxp.child_value(config, 'vifname')
+ rate = sxp.child_value(config, 'rate')
ipaddr = _get_config_ipaddr(config)
devid = self.allocateDeviceID()
back['bridge'] = bridge
if vifname:
back['vifname'] = vifname
+ if rate:
+ back['rate'] = parseRate(rate)
return (devid, back, front)
result = DevController.configuration(self, devid)
- (script, ip, bridge, mac, typ, vifname) = self.readBackend(
- devid, 'script', 'ip', 'bridge', 'mac', 'type', 'vifname')
+ (script, ip, bridge, mac, typ, vifname, rate) = self.readBackend(
+ devid, 'script', 'ip', 'bridge', 'mac', 'type', 'vifname', 'rate')
if script:
result.append(['script',
result.append(['type', typ])
if vifname:
result.append(['vifname', vifname])
+ if rate:
+ result.append(['rate', formatRate(rate)])
return result